<template>
  <div class="play-container">
    <el-card class="box-card">
      <template #header>
        <div class="card-header">
          <span>视频播放 (HLS)</span>
        </div>
      </template>
      <div class="video-container">
        <video
          id="videoElement"
          ref="videoRef"
          controls
          autoplay
          muted
          playsinline
          width="100%"
          height="600"
        >
        </video>
        <p id="status">正在初始化播放器...</p>
      </div>
    </el-card>
  </div>
</template>

<script setup lang="ts">
import { onMounted, onBeforeUnmount, ref, getCurrentInstance } from 'vue';
import { useRoute } from 'vue-router';

const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const route = useRoute();
const videoRef = ref<HTMLVideoElement | null>(null);
let hlsPlayer: any = null;

const initPlayer = () => {
  const videoElement = document.getElementById('videoElement') as HTMLVideoElement;
  const statusElement = document.getElementById('status');

  if (!videoElement || !statusElement) return;

  // 设置初始状态
  statusElement.textContent = '';

  // 处理 URL 编码
  let streamUrl = route.query.rtmpUrl as string;

  // 解码URL
  try {
    // 处理多重编码的情况
    while (streamUrl.includes('%')) {
      try {
        streamUrl = decodeURIComponent(streamUrl);
      } catch (e) {
        // 如果解码失败，说明已经解码完成
        break;
      }
    }
  } catch (e) {
    console.error('URL解码失败:', e);
  }

  // 如果存在旧的播放器，先销毁
  if (hlsPlayer) {
    hlsPlayer.destroy();
    hlsPlayer = null;
  }

  // 检查浏览器是否原生支持 HLS
  if (videoElement.canPlayType('application/vnd.apple.mpegurl')) {
    // 原生支持 HLS
    videoElement.src = streamUrl;
    videoElement.addEventListener('loadedmetadata', () => {
      statusElement.textContent = '';
      videoElement.muted = true;
    });
  } else if ((window as any).Hls.isSupported()) {
    // 使用 hls.js
    hlsPlayer = new (window as any).Hls({
      debug: false,
      enableWorker: true,
      lowLatencyMode: true,
      backBufferLength: 90
    });

    hlsPlayer.loadSource(streamUrl);
    hlsPlayer.attachMedia(videoElement);

    hlsPlayer.on((window as any).Hls.Events.MANIFEST_PARSED, () => {
      videoElement.play().catch((error: any) => {
        console.error('播放失败:', error);
        statusElement.textContent = '播放失败: ' + error.message;
      });
    });

    hlsPlayer.on((window as any).Hls.Events.ERROR, (event: any, data: any) => {
      if (data.fatal) {
        switch (data.type) {
          case (window as any).Hls.ErrorTypes.NETWORK_ERROR:
            console.error('网络错误，尝试恢复...');
            hlsPlayer.startLoad();
            break;
          case (window as any).Hls.ErrorTypes.MEDIA_ERROR:
            console.error('媒体错误，尝试恢复...');
            hlsPlayer.recoverMediaError();
            break;
          default:
            console.error('无法恢复的错误');
            hlsPlayer.destroy();
            break;
        }
      }
      statusElement.textContent = '播放错误: ' + data.details;
    });
  } else {
    statusElement.textContent = '您的浏览器不支持 HLS 播放';
  }

  // 监听视频事件
  videoElement.addEventListener('error', (e) => {
    console.error('视频错误:', e);
    statusElement.textContent = '视频播放出错，正在重试...';
  });

  videoElement.addEventListener('play', () => {
    statusElement.textContent = '正在播放...';
  });

  videoElement.addEventListener('pause', () => {
    if (!videoElement.paused) return;
    statusElement.textContent = '已暂停';
  });
};

onMounted(() => {
  // 动态加载 hls.js
  const script = document.createElement('script');
  script.src = 'https://cdn.jsdelivr.net/npm/hls.js@latest';
  script.onload = () => {
    initPlayer();
  };
  document.head.appendChild(script);
});

onBeforeUnmount(() => {
  if (hlsPlayer) {
    hlsPlayer.destroy();
    hlsPlayer = null;
  }
});
</script>

<style scoped>
.play-container {
  padding: 20px;
}

.video-container {
  width: 100%;
  max-width: 1200px;
  margin: 0 auto;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

#videoElement {
  width: 100%;
  height: 600px;
  background-color: #000;
}

#status {
  margin-top: 10px;
  text-align: center;
}
</style>
